﻿/*
Autor...: Ivan M. Kruger
Empresa.: Home Kruger
Data....: 03/03/2011
*/

using System;
using System.Collections.Generic;
using System.Text;

namespace ik.ExtensionMethor
{
    public static class ExtensionMethods
    {
        /*
        Exemplos
        --------

        using Kruger.Suite.Extension;

        DateTime dt = new DateTime();
        dt = dt.isToday();
        MessageBox.Show(dt.ToString());

        int i = 3;
        MessageBox.Show(i.MascaraInteiro(10));

        decimal dec = 10;
        MessageBox.Show(dec.MascaraDecimal(null));

        MessageBox.Show("abc".isDecimal().ToString());
        */

        #region "Extension Methods - Outros"
        //reference: System.Speesh
        //public static void Pronunciar(this String textSpeak)
        //{
        //    System.Speech.Synthesis.SpeechSynthesizer ss = new System.Speech.Synthesis.SpeechSynthesizer();
        //    ss.Speak(textSpeak);
        //}
        #endregion


        #region "Extension Methods - Strings"

        /// <summary>
        /// retira caracter de uma string
        /// </summary>
        /// <param name="strTxt">string origem</param>
        /// <param name="ltr">caracter a remover</param>
        /// <returns>string</returns>
        public static String RemoveChar(this String s, String ltr)
        {
            for (int i = 0; i < ltr.Length; i++)
                s = s.Replace(ltr.Substring(i, 1), "");
            return s;
        }

        /// <summary>
        /// retorna (n) caracteres contando da direita para esquerda
        /// </summary>
        /// <param name="s">string</param>
        /// <param name="length">valor</param>
        /// <returns>string</returns>
        public static String Right(this String s, Int32 length)
        {
            length = Math.Max(length, 0);

            if (s.Length > length)
                return s.Substring(s.Length - length, length);
            else
                return s;
        }

        /// <summary>
        /// retorna (n) caracteres contando da esquerda para direita
        /// </summary>
        /// <param name="s">string</param>
        /// <param name="length">valor</param>
        /// <returns>string</returns>
        public static String Left(this String s, Int32 length)
        {
            length = Math.Max(length, 0);

            if (s.Length > length)
                return s.Substring(0, length);
            else
                return s;
        }
        
        
        /// <summary>
        /// Remove acentos de uma string
        /// </summary>
        /// <param name="s">string</param>
        /// <returns>string sem acentos</returns>
        public static String RemoveAcentos(this String s)
        {
            string _stFormD = s.Normalize(NormalizationForm.FormD);
            StringBuilder _sb = new StringBuilder();

            for (int ich = 0; ich < _stFormD.Length; ich++)
            {
                System.Globalization.UnicodeCategory _uc = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(_stFormD[ich]);
                if (_uc != System.Globalization.UnicodeCategory.NonSpacingMark)
                {
                    _sb.Append(_stFormD[ich]);
                }
            }
            return (_sb.ToString().Normalize(NormalizationForm.FormC));
        }

        /// <summary>
        /// remove números de uma string
        /// </summary>
        /// <param name="s">string</param>
        /// <returns>string sem números</returns>
        public static String RemoveNonNumeric(this String s)
        {
            System.Text.RegularExpressions.MatchCollection _col = System.Text.RegularExpressions.Regex.Matches(s, "[0-9]");
            StringBuilder _sb = new StringBuilder();
            foreach (System.Text.RegularExpressions.Match m in _col)
                _sb.Append(m.Value);
            return _sb.ToString();
        }

        /// <summary>
        /// valida se o e-mail é válido
        /// </summary>
        /// <param name="s">string</param>
        /// <returns>boolean</returns>
        public static Boolean isValidEmail(this String s)
        {
            try
            {
                System.Text.RegularExpressions.Regex _regex = new System.Text.RegularExpressions.Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
                return _regex.IsMatch(s);
            }
            catch (Exception) { return false; }
        }

        /// <summary>
        /// inverte a string
        /// </summary>
        /// <param name="s">string</param>
        /// <returns>string inversa</returns>
        public static String Reverse(this String s)
        {
            try
            {
                char[] _chars = s.ToCharArray();
                Array.Reverse(_chars);
                return new String(_chars);
            }
            catch (Exception) { return s; }
        }

        #endregion


        #region "Extension Methods - Date e Time"
        /// <summary>
        /// DateDiff in SQL style. 
        /// Datepart implemented: 
        ///     "year" (abbr. "yy", "yyyy"), 
        ///     "quarter" (abbr. "qq", "q"), 
        ///     "month" (abbr. "mm", "m"), 
        ///     "day" (abbr. "dd", "d"), 
        ///     "week" (abbr. "wk", "ww"), 
        ///     "hour" (abbr. "hh"), 
        ///     "minute" (abbr. "mi", "n"), 
        ///     "second" (abbr. "ss", "s"), 
        ///     "millisecond" (abbr. "ms").
        /// </summary>
        /// <param name="DatePart"></param>
        /// <param name="EndDate"></param>
        /// <returns></returns>
        public static Int64 DateDiff(this DateTime StartDate, String DatePart, DateTime EndDate)
        {
            Int64 _DateDiffVal = 0;
            System.Globalization.Calendar _cal = System.Threading.Thread.CurrentThread.CurrentCulture.Calendar;
            TimeSpan _ts = new TimeSpan(EndDate.Ticks - StartDate.Ticks);
            switch (DatePart.ToLower().Trim())
            {
                #region year
                case "year":
                case "yy":
                case "yyyy":
                    _DateDiffVal = (Int64)(_cal.GetYear(EndDate) - _cal.GetYear(StartDate));
                    break;
                #endregion

                #region quarter
                case "quarter":
                case "qq":
                case "q":
                    _DateDiffVal = (Int64)((((_cal.GetYear(EndDate)
                                        - _cal.GetYear(StartDate)) * 4)
                                        + ((_cal.GetMonth(EndDate) - 1) / 3))
                                        - ((_cal.GetMonth(StartDate) - 1) / 3));
                    break;
                #endregion

                #region month
                case "month":
                case "mm":
                case "m":
                    _DateDiffVal = (Int64)(((_cal.GetYear(EndDate)
                                        - _cal.GetYear(StartDate)) * 12
                                        + _cal.GetMonth(EndDate))
                                        - _cal.GetMonth(StartDate));
                    break;
                #endregion

                #region day
                case "day":
                case "d":
                case "dd":
                    _DateDiffVal = (Int64)_ts.TotalDays;
                    break;
                #endregion

                #region week
                case "week":
                case "wk":
                case "ww":
                    _DateDiffVal = (Int64)(_ts.TotalDays / 7);
                    break;
                #endregion

                #region hour
                case "hour":
                case "hh":
                    _DateDiffVal = (Int64)_ts.TotalHours;
                    break;
                #endregion

                #region minute
                case "minute":
                case "mi":
                case "n":
                    _DateDiffVal = (Int64)_ts.TotalMinutes;
                    break;
                #endregion

                #region second
                case "second":
                case "ss":
                case "s":
                    _DateDiffVal = (Int64)_ts.TotalSeconds;
                    break;
                #endregion

                #region millisecond
                case "millisecond":
                case "ms":
                    _DateDiffVal = (Int64)_ts.TotalMilliseconds;
                    break;
                #endregion

                default:
                    throw new Exception(String.Format("DatePart \"{0}\" is unknown", DatePart));
            }
            return _DateDiffVal;
        }

        /// <summary>
        /// retorna a última data do mês
        /// </summary>
        /// <param name="d">data</param>
        /// <returns>datetime</returns>
        public static DateTime GetLastDayOfMonth(this DateTime d)
        {
            return new DateTime(d.Year, d.Month, 1).AddMonths(1).AddDays(-1);
        }

        /// <summary>
        /// retorna a data e hora atual
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public static DateTime GetToday(this DateTime d)
        {
            return DateTime.Now;
        }
        #endregion


        #region "Mascara números"
        /// <summary>
        /// extension methors Int16; formata com zeros a esquerda
        /// </summary>
        /// <param name="i">valor do inteiro</param>
        /// <param name="length">número de casas</param>
        /// <returns>string formatada</returns>
        public static String MascaraInteiro(this Int16 i, Int32 length)
        { return MascaraInteiro((Int64)i, length); }

        /// <summary>
        /// extension methors Int32; formata com zeros a esquerda
        /// </summary>
        /// <param name="i">valor do inteiro</param>
        /// <param name="length">número de casas</param>
        /// <returns>string formatada</returns>
        public static String MascaraInteiro(this Int32 i, Int32 length)
        { return MascaraInteiro((Int64)i, length); }

        /// <summary>
        /// extension methors Int64; formata com zeros a esquerda
        /// </summary>
        /// <param name="i">valor do inteiro</param>
        /// <param name="length">número de casas</param>
        /// <returns>string formatada</returns>
        public static String MascaraInteiro(this Int64 i, Int32 length)
        {
            return String.Format("{0:D" + length.ToString() + "}", i);
        }

        /// <summary>
        /// extension methors Decimal; formata com mascara de valor
        /// </summary>
        /// <param name="d">valor a formatar</param>
        /// <param name="msc">mascara de valor / null</param>
        /// <returns>string formatada</returns>
        public static String MascaraDecimal(this Decimal d, String msc)
        {
            if (msc == null)
                msc = "###,##0.00";
            return d.ToString(msc);
        }

        /// <summary>
        /// extension methors String; verifica se valor é decimal
        /// </summary>
        /// <param name="d">valor a checar</param>
        /// <returns>Boolean</returns>
        public static Boolean isDecimal(this String d)
        { { try { Decimal _test = Decimal.Parse(d); return true; } catch (Exception) { return false; } } }

        /// <summary>
        /// extension methors String; verifica se valor é Int16
        /// </summary>
        /// <param name="d">valor a checar</param>
        /// <returns>Boolean</returns>
        public static Boolean isInt16(this String d)
        { { try { Decimal _test = Int16.Parse(d); return true; } catch (Exception) { return false; } } }

        /// <summary>
        /// extension methors String; verifica se valor é Int32
        /// </summary>
        /// <param name="d">valor a checar</param>
        /// <returns>Boolean</returns>
        public static Boolean isInt32(this String d)
        { { try { Decimal _test = Int32.Parse(d); return true; } catch (Exception) { return false; } } }

        /// <summary>
        /// extension methors String; verifica se valor é Int64
        /// </summary>
        /// <param name="d">valor a checar</param>
        /// <returns>Boolean</returns>
        public static Boolean isInt64(this String d)
        { { try { Decimal _test = Int64.Parse(d); return true; } catch (Exception) { return false; } } }

        /// <summary>
        /// convert string in Int32 value
        /// </summary>
        /// <param name="d">check value</param>
        /// <returns>Int32</returns>
        public static Int32 TryParseInt32(this String d)
        { try { return Convert.ToInt32(d); } catch (Exception ex) { throw ex; } }

        #endregion


    }
}
